
/**
 * Robot.java
 * Descripción: Clase que representa al robot explorador y le permite explorar
 *              el mapa buscando el siguiente nodo.
 * @since 07/11/2012
 * @version 1.5
 * @author Diego García, Carnet 11360
 *         Oscar Castañeda, Carnet 11086 
 *         Luis Carlos Velásquez, Carnet 11085
 *         Sergio Argueta, Carnet 11029
 */

public class Robot {
       
    private int fila;          //Coordenada en fila del robot.
    private int col;           //Coordenada en columna del robot.    
    private int direccion;     //Dirección en la cual está el robot orientado actualmente. 1 para este; 2: norte; 3: oeste y 4:sur.
    public int[][] posiciones; //Coordenadas en donde hay nodos.
    private int head;           //Número de vectores visitados; para indicar la posición actual ocupada en posiciones.
    private Mapa mapa;
    
    /**
     * Construye un  nuevo robot, el cual está orientado hacia el este y en la esquina superior izquierda del mapa.
     */
    public Robot(){
        fila = 0;
        col = 0;
        direccion = 1;
        posiciones = new int[64][2];
        head = 0;
        mapa = new Mapa(8);
    }
    
    /**
     * Getter de la fila del robot.
     * @return int con la fila en la cual se encuentra el robot.
     */
    public int getFila(){
        return fila;
    }
    
    /**
     * Getter de la columna donde se encuentra ubicado el robot.
     * @return int con la columna en la cual se encuentra el robot.
     */    
    public int getCol(){
        return col;
    }
    
    /**
     * Verifica si la coordenada ingresada no se encuentra agregada a la lista de posiciones
     * de nodos del robot.
     * @param fila Fila de la coordenda a verificar.
     * @param col Columna de la coordenada a verificar.
     * @return True si aún no está agregada; false si ya está agregada.
     */
    public boolean estaNoAgregado(int fila, int col){        
        for (int i=0; i<head; i++){
            if (posiciones[i][0]==fila && posiciones[i][1]==col) return false;
        }
        return true;
        }
    
    /**
     * Permite al robot buscar el siguiente nodo.
     * @return int con las carácterísticas del espacio al cual se ha avanzado:
     *         Si es múltiplo de 2, tiene camino derecho;
     *         si es múltiplo de 3, tiene camino enfrente;
     *         si es múltiplo de 5 tiene camino izquierdo.
     *         si es 0, esta en un rincón.
     */
    public int buscar_nodo(){
    	
//        int b=3;
//        while (b==3){
//            //Se avanza mientras solo haya camino para enfrente.
//            b=avanzar();          
//        }        
//        
//        //Si se ha llegado a un nodo ya conocido, es porque ya ha sido explorado, por lo que se
//        //toma como que se hubiese llegado a un tope.
//        else return 0;
//        //Se devuelve la descripción de los lugares libres alrededor del nodo.
//        return b;
        
    	int resultado = enviar.comunicacion(0);
    	int numeroPasos = resultado % 100;
    	numeroPasos = numeroPasos/10;
    	//Al terminar es porque ya no hay camino solo enfrente y se ha llegado a un
    	//nodo. Se agrega dicho nodo de no estar agregado.
    	for (int i=0; i < numeroPasos; i++ ){
    		moverAdelante();
    		System.out.println("Mover Fila: " +  fila + " columna: " + col);
    	}
    	if (estaNoAgregado(fila,col)){
    		agregarPosicion(fila,col);
    	}else return 1; 
    	
    	return resultado/100;
    }
    
    /**
     * Permite al robot regresar al nodo anterior.
     * @return int con las carácterísticas del espacio al cual ha regresado:
     *         Si es múltiplo de 2, tiene camino derecho;
     *         si es múltiplo de 3, tiene camino enfrente;
     *         si es múltiplo de 5 tiene camino izquierdo.
     *         si es 0, esta en un rincón.
     */
    public void regresar(){
    	int resultado = enviar.comunicacion(0);
    	int numeroPasos = resultado % 100;
    	numeroPasos = numeroPasos/10;
    	//Al terminar es porque ya no hay camino solo enfrente y se ha llegado a un
    	//nodo. Se agrega dicho nodo de no estar agregado.
    	for (int i=0; i < numeroPasos; i++ ){
    		moverAdelante();
    		System.out.println("Mover Regreso Fila: " +  fila + " columna: " + col);
    	}    	
    }
    
    /**
     * Agrega una posición a la lista de nodos. 
     * @param fila Fila de la posición a agregar.
     * @param col Columna de la posición a agregar.
     */
    public void agregarPosicion(int fila, int col){
        posiciones[head][0]=fila;
        posiciones[head][1]=col;
        head++;
    }
    
    /**
     * Permite al robot girar hacia la derecha.
     * @param num int con el número de giros a dar.
     */
    public void turn(int num){
        if (num==1){
            direccion=(byte) (direccion-1);
            if (direccion==0) direccion=4;        	
        }
        if (num==2){
            direccion=(byte) (direccion-2);
            if (direccion==0) direccion=4;
            if (direccion==-1) direccion=3;
        }
        if (num==3){
            direccion=(byte) (direccion+1);
        if (direccion==5) direccion=1;
        }
        enviar.comunicacion(num);
    }
        
    /**
     * Permite al robot avanzar un paso hacia delante.
     */
    public void moverAdelante(){
        if (direccion==1) col++;
        if (direccion==2) fila--;
        if (direccion==3) col--;
        if (direccion==4) fila++;
        System.out.println("Fila: "+fila+", columna: "+col);
    }
        
    /**
     * Permite al robot avanzar un paso hacia delante y revisar su entorno.
     * @return int con la descripción del área que lo rodea:
     *         Si es múltiplo de 2, tiene camino derecho;
     *         si es múltiplo de 3, tiene camino enfrente;
     *         si es múltiplo de 5 tiene camino izquierdo.
     *         si es 0, esta en un rincón.
     */
    public int avanzar(){            
        moverAdelante();
        return verAlrededores();                    
    }
      
    /**
     * Permite al robot revisar su entorno.
     * @return int con la descripción del área que lo rodea:
     *         Si es múltiplo de 2, tiene camino derecho;
     *         si es múltiplo de 3, tiene camino enfrente;
     *         si es múltiplo de 5 tiene camino izquierdo.
     *         si es 0, esta en un rincón.
     */
    public int verAlrededores(){
        int toRet =1;
        if (mapa.libreEnfrente(fila, col, direccion)){
            toRet = toRet*3;
        }
        if (mapa.libreDerecha(fila, col, direccion)){
            toRet = toRet*2;
        }
        if (mapa.libreIzquierda(fila, col, direccion)){
            toRet = toRet*5;
        }
        return toRet;
    }
        
    /**
     * Devuelve el mapa del robot.
     * @return Mapa
     */
    public Mapa getMapa(){
        return mapa;
    }
        
    /**
     * Gira al robot hacia la dirección dada.
     * @param directRouteDirection 1 para Este, 2 para norte, 3 para oeste y 4 para sur.
     */
    public void girarEnDireccion(int direction) {
        //El robot gira hasta estar orientado en el valor indicado por el parámetro.
        while(direccion != direction){
            turn(1);
        }
    }
    
}